package com.zhuiyun.pm.client.bid.chat.service;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhuiyun.pm.client.bid.chat.entity.BidRecord;
import com.zhuiyun.pm.client.bid.chat.entity.SocketMsg;
import com.zhuiyun.pm.client.bid.chat.model.BidRecordModel;
import com.zhuiyun.pm.client.bid.response.CommonConstants;
import com.zhuiyun.pm.client.bid.util.DateTimeUtils;
import com.zhuiyun.pm.config.SpringContextUtil;
import com.zhuiyun.pm.utils.RedisUtil;
import org.json.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 * 拍卖服务器
 * @ClassName WebSocketChatServer
 * @Description TODO
 * @Author lyp
 * @Date 2023/3/14 14:14
 **/
@ServerEndpoint(value = "/websocket/{roomName}/{userName}/{loginName}")
@Service
@Component
public class WebSocketChatServer {


    /**
     * 用来保存房间号
     */
    private static final Map<String,Map<String,Session>> rooms = new ConcurrentHashMap();
    //    private static final Map userList=null;
    private static Lock lock = new ReentrantLock();
    /**
     * 会话session
     */
    private Session session;

    /**
     *
     * 创建聊天房间  / 加入聊天房间
     * @param session
     * @param roomName 房间编号 唯一值
     * @param userName 用户登录账号 唯一值
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("roomName")String roomName, @PathParam("userName") String userName,@PathParam("loginName") String loginName) {
        this.session = session;
        Map userList = null;
        if(!rooms.containsKey(roomName)){
            userList = new ConcurrentHashMap();
            userList.put(userName,session);
            rooms.put(roomName,userList);
        }else {
            userList =  rooms.get(roomName);
            userList.put(userName,session);
        }
        System.out.println("有新连接加入:"+userName+"当前房间数为:"+userList.size()+"当前在线人数为" + userList.size() + "登录名为" + loginName);
        //this.session.getAsyncRemote().sendText("恭喜:"+userName+" 成功连接上WebSocket(其频道号："+session.getId()+")-->当前在线人数为："+userList.size());
    }

    /**
     * 接收消息并群发
     * @param roomName
     * @param userName
     * @param msg 消息
     * @param session
     * @throws Exception
     */
    @OnMessage
    public void receiveMsg(@PathParam("roomName") String roomName,@PathParam("userName") String userName,@PathParam("loginName") String loginName, String msg, Session session) throws Exception {
        System.out.println(msg);//接收到信息后进行广播
        if("heartCheck".equals(msg)){
            System.out.println("心跳数据");
        }else{
            System.out.println(msg);
            broadcast(roomName,userName, msg,loginName);
        }
    }
    /**
     * 按照房间名进行广播
     * @param roomName
     * @param msg
     * @throws Exception
     */
    public void broadcast(String roomName,String useName, String msg,String loginName) throws Exception {
        // 获取redis工具类对象
        RedisUtil redisUtil = SpringContextUtil.getBean(RedisUtil.class);
        //创建ObjectMapper 将msg json数据映射成对象
        ObjectMapper objectMapper = new ObjectMapper();
        SocketMsg socketMsg = objectMapper.readValue(msg, SocketMsg.class);
        // 当前价格
        int now_price = socketMsg.getPrice() + socketMsg.getBasePrice();
        // 房间key
        String MAX_PRICE_KEY = CommonConstants.ROOM_AUCTION_PRICE + roomName;
        String MAX_PRICE_USER_KEY =CommonConstants.ROOM_AUCTION_USER+ roomName;
        String BID_RECORD_KEY =CommonConstants.BID_RECORD+ roomName;
        String ROOM_LOGIN_USER = CommonConstants.ROOM_LOGIN_USER + roomName;
        // 读取最高竞价
        int max_price;
        if(redisUtil.get(MAX_PRICE_KEY) == null){
            max_price = now_price;
            redisUtil.set(MAX_PRICE_KEY,max_price);
            redisUtil.set(MAX_PRICE_USER_KEY,useName);
        }else{
            max_price = now_price;
            redisUtil.set(MAX_PRICE_KEY,now_price);
            redisUtil.set(MAX_PRICE_USER_KEY,useName);
        }
        // 获取出价时间
        Date date = new Date();
//        try{
//            lock.lock();
//            // 首次出价将首次出价人设为最高出价人
//            if(max_price==0){
//                max_price = now_price;
//                redisUtil.set(MAX_PRICE_KEY,max_price);
//                redisUtil.set(MAX_PRICE_USER_KEY,useName);
//            }else{
//                // 判断当前出价是否为最高出价 如果是存入当前出价人数据
//                if(max_price.compareTo(now_price)<0){
//                    max_price = now_price;
//                    redisUtil.set(MAX_PRICE_KEY,now_price);
//                    redisUtil.set(MAX_PRICE_USER_KEY,useName);
//                }
//            }
//        }catch (Exception e){
//            e.printStackTrace();
//        }finally {
//            lock.unlock();
//        }
        // 封装最高出价数据和出价人  返回前端页面
        BidRecord bidRecord = new BidRecord(0,useName,loginName,now_price,max_price,date,false,roomName);
        BidRecordModel bidRecordModel = new BidRecordModel(0,useName,loginName,now_price,max_price,DateTimeUtils.format("yyyy-MM-dd HH:mm:ss.SSS",date),false,roomName);
        // 判断是否是最高出价人
//        if(max_price.compareTo(now_price)==0){
        bidRecord.setMaxBidUserId(true);
//        }
        // 获取所有房间内的用户
        Map<String, Session> userList = rooms.get(roomName);
        // 将记录存入redis 竞拍结束后将记录存储到数据库
        redisUtil.lSet(BID_RECORD_KEY,bidRecord);
        JSONObject jsonObject = new JSONObject(bidRecordModel);
        // 根据房价号群发消息
        System.out.println("当前房间人数++++++++++++++++++++++++"+userList.size());
        for(Session s : userList.values()) {
            if(s.isOpen()){
                s.getBasicRemote().sendText(jsonObject.toString());
            }
        }
    }
}
